// f35modbus.cpp

#include <Winsock2.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])

{
	char *ip_adrs="192.168.1.106";
	unsigned char unit = 0xFE;
	unsigned short reg_no = 0x0000;
	unsigned short num_regs = 0x0001;
	
	printf("ip_adrs = %s unit = %d reg_no = %d num_regs = %d\n",ip_adrs, unit, reg_no, num_regs);
	
	// initialize WinSock
	static WSADATA wd;
	if (WSAStartup(0x0101, &wd))
	{printf("cannot initialize WinSock\n");
	return 1;
	}
	
	// set up socket
	SOCKET s;
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(502); // ASA standard port
	server.sin_addr.s_addr = inet_addr(ip_adrs);
	int i;
	i = connect(s, (sockaddr *)&server, sizeof(sockaddr_in));
	if (i<0)
	{
		printf("connect - error %d\n",WSAGetLastError());
		closesocket(s);
		WSACleanup();
		return 1;
	}
	fd_set fds;
	FD_ZERO(&fds);
	timeval tv;
	tv.tv_sec = 5;
	tv.tv_usec = 0;
	
	// wait for permission to send
	FD_SET(s, &fds);
	i = select(32, NULL, &fds, NULL, &tv); // write
	if (i<=0)
	{
		printf("select - error %d\n",WSAGetLastError());
		closesocket(s);
		WSACleanup();
		return 1;
	}
	
	// build request of form 0 0 0 0 0 6 ui 3 rr rr nn nn
	char obuf[261];
	char ibuf[261];
	for (i=0;i<5;i++) obuf[i] = 0;
	obuf[5] = 6;
	obuf[6] = unit;
	obuf[7] = 3;
	obuf[8] = reg_no >> 8;
	obuf[9] = reg_no & 0xff;
	obuf[10] = num_regs >> 8;
	obuf[11] = num_regs & 0xff;
	
	// send request
	i = send(s, obuf, 12, 0);
	if (i<12)
	{
		printf("failed to send all 12 chars\n");
	}
	
	// wait for response
	FD_SET(s, &fds);
	i = select(32, &fds, NULL, NULL, &tv); //read
	if (i<=0)
	{
		printf("no TCP response received\n");
		closesocket(s);
		WSACleanup();
		return 1;
	}
	
	// read response
	i = recv(s, ibuf, strlen(ibuf)+1, 0);
	if (i<9)
	{
		if (i==0)
		{
			printf("unexpected close of connection at remote end\n");
		}
		else
		{
			printf("response was too short - %d chars\n", i);
		}
	}
	else if (ibuf[7] & 0x80)
	{
		printf("MODBUS exception response - type %d\n", ibuf[8]);
	}
	else if (i != (9+2*num_regs))
	{
		printf("incorrect response size is %d expected %d\n",i,(9+2*num_regs));
	}
	else
		{
		for (i=0;i<num_regs;i++ )
		{unsigned short w = (ibuf[9+i+i]<<8) + ibuf[10+i+i];
		printf("word %d = %d\n", i, w);
		}
	}
	
	// close down
	closesocket(s);
	WSACleanup();
	return 0;
}